package lyj.springcloud.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.lyj.springcloud.entities.CommonResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

/**
 * 通过ribbon 负载均衡
 */
@RestController
public class OrderRibbonNacosController {


    public static final String SERVICE_URL = "http://nacos-payment-provider";

    @Resource
    private RestTemplate restTemplate;

    /**
     * @SentinelResource 属性详解：
     *      fallback：该属性只负责业务异常,发生业务异常时，则走配置的fallback兜底方法
     *      blockHandler：只负责sentinel控制台配置的违规
     *      1，没有配置blockHandler 及 fallback属性 ：默认的流控报错，系统异常时：显示error page
     *      2，配置blockHandler：当违反sentinel控制台配置是，走配置的blockHandler兜底方法
     *      3，blockHandler与fallback都配置了，当违反sentinel配置规则时，走blockHandler配置的兜底方法；业务异常，则走fallback配置的服务熔断兜底方法
     * @param id
     * @return
     */
    @GetMapping("/order/fallBack/{id}")
    //@SentinelResource(value = "fallBack")
    //@SentinelResource(value = "fallBack",blockHandler = "fall_Back" )
    @SentinelResource(value = "fallBack",blockHandler = "block_Handler_method",
            fallback = "fall_back_method",// 在抛出异常的时候提供 fallback 处理逻辑
            exceptionsToIgnore = IllegalArgumentException.class)// 忽略异常
    public CommonResult fallBack(@PathVariable("id") String id) {
        CommonResult result = restTemplate.getForObject(SERVICE_URL  + "/paymentSQL/" + id, CommonResult.class);
        if (id.equalsIgnoreCase("4")) {
            throw new IllegalArgumentException ("IllegalArgumentException,非法参数异常....");
        }else if (result.getData() == null) {
            throw new RuntimeException ("该ID没有对应记录,空指针异常");
        }
        return result;
    }

    /**
     * 触发sentinel控制台配置时的兜底方法
     * @param id
     * @param e
     * @return
     */
    public CommonResult block_Handler_method(String id , BlockException e) {
        return new CommonResult("500",e.getClass().getSimpleName() + "，违反sentinel配置的限流规则，id : " + id);
    }

    /**
     * 业务异常触发服务熔断的服务降级方法
     * @param id
     * @return
     */
    public CommonResult fall_back_method(String id,Throwable throwable) {
        return new CommonResult("500" , "服务异常，熔断 兜底方法: " + throwable.getMessage());
    }


}
